#pragma once

#include <boost/asio.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/core.hpp>
#include <functional>
#include <string>
#include <memory>
#include <unordered_map>
#include <atomic>
#include <nlohmann/json.hpp>
#include <unordered_map>
#include <mutex>
#include <chrono>
#include <array>
#include <optional>

namespace gateway::beast_http {

using RequestHandler = std::function<void(
    boost::beast::http::request<boost::beast::http::string_body>&,
    boost::beast::http::response<boost::beast::http::string_body>&)>;

class Router;

struct GatewaySettings {
    bool access_log_enable = true;
    struct Jwt {
        bool enable = false;
        bool require_signature = false; // 是否强制验签
        std::string secret;
        std::string alg = "HS256";     // 支持 HS256 | RS256
        std::string public_key_path;    // RS256 公钥路径（PEM）
        std::string issuer;             // 期望 iss（可选）
        std::vector<std::string> audience; // 期望 aud（可选，支持数组）
        std::unordered_map<std::string, std::string> key_paths; // kid -> PEM path
    } jwt;
    struct RateLimit {
        bool enable = false;
        int rps = 1000; // 每秒请求上限（进程级）
        std::string mode = "global"; // global|ip|path|ip_path
        int burst = 0; // 令牌桶突发
        // 白名单/黑名单 + 分布式限流占位
        std::vector<std::string> whitelist_ips;
        std::vector<std::string> blacklist_ips;
        std::vector<std::string> whitelist_paths;
        std::vector<std::string> blacklist_paths;
        bool redis_enable = false;
        std::string redis_prefix = "gw:rl";
    } rl;
    struct Authz {
        // 简单授权：按路径前缀需要任一角色
        // 形如：[{prefix:"/api/admin", roles:["admin"]}]
        struct Rule { std::string prefix; std::vector<std::string> roles; };
        std::vector<Rule> rules;
    } authz;
};

class HttpServer {
public:
    HttpServer(const std::string& host,
               unsigned short port,
               int io_threads,
               int worker_threads);

    // 设置路由器
    void set_router(std::shared_ptr<Router> router);

    // 设置网关运行参数
    void set_settings(const GatewaySettings& s) { settings_ = s; }

    // 启动（阻塞直到停止）
    void run();

    // 优雅停止
    void stop();

private:
    void do_accept();
    void start_session(boost::asio::ip::tcp::socket socket);

    // 访问日志
    void log_access(const std::string& remote,
                    const std::string& req_line,
                    unsigned status,
                    std::size_t bytes,
                    long long elapsed_ms,
                    const std::string& request_id) const;

    // 限流（简单进程级计数窗口）
    bool allow_request();
    bool allow_request_key(const std::string& key);
    
    // 授权：根据路径前缀与角色要求做授权判定
    bool authorize_path(const std::string& path, const nlohmann::json& claims) const;

    // /metrics 输出
    boost::beast::http::response<boost::beast::http::string_body> make_metrics_response(unsigned http_version) const;

    bool validate_jwt_token(const std::string& token,
                            nlohmann::json& claims,
                            std::string& error) const;
#ifdef OPENSSL_FOUND
    std::optional<std::string> resolve_rs256_key(const std::string& kid) const;
    std::optional<std::string> load_pem_from_file(const std::string& path) const;
#endif

private:
    std::string host_;
    unsigned short port_;
    int io_threads_;
    int worker_threads_;

    std::unique_ptr<boost::asio::io_context> ioc_;
    std::unique_ptr<boost::asio::thread_pool> worker_pool_;
    std::unique_ptr<boost::asio::ip::tcp::acceptor> acceptor_;
    std::shared_ptr<Router> router_;
  GatewaySettings settings_{};

    // 限流状态
    std::atomic<std::uint64_t> rl_sec_{0};
    std::atomic<std::uint64_t> rl_count_{0};
    struct TokenBucket { uint64_t sec{0}; int tokens{0}; };
    mutable std::mutex rl_mutex_;
    std::unordered_map<std::string, TokenBucket> rl_buckets_;

    // Metrics（Prometheus 文本格式）
    mutable std::atomic<std::uint64_t> metric_req_total_{0};
    mutable std::atomic<std::uint64_t> metric_resp_2xx_{0};
    mutable std::atomic<std::uint64_t> metric_resp_4xx_{0};
    mutable std::atomic<std::uint64_t> metric_resp_5xx_{0};
    mutable std::atomic<std::uint64_t> metric_bytes_out_{0};
    mutable std::atomic<std::uint64_t> metric_in_flight_{0};
    mutable std::atomic<std::uint64_t> metric_ws_msg_total_{0};
    // Latency histogram (ms)
    inline static const std::array<int,10> kLatencyBounds{5,10,25,50,100,250,500,1000,2500,5000};
    std::array<std::atomic<std::uint64_t>, 10> metric_latency_buckets_{};
    mutable std::atomic<std::uint64_t> metric_latency_sum_ms_{0};
    mutable std::atomic<std::uint64_t> metric_latency_count_{0};
    // Per-service counters
    mutable std::mutex metric_mtx_;
    mutable std::unordered_map<std::string, std::uint64_t> metric_service_total_;

#ifdef OPENSSL_FOUND
    // 缓存RS256公钥内容（懒加载）
    mutable std::mutex rs256_key_mutex_;
    mutable std::unordered_map<std::string, std::string> rs256_key_cache_;
#endif
};

} // namespace gateway::beast_http
